﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Net;
using WomanMotion.WebApi.Api.Utility;
using WomanMotion.WebApi.Infrastructure.DataBaseCommon;
using WomanMotion.WebApi.Infrastructure.UnifyResult;
using WomanMotion.WebApi.Model.Dtos.Users;
using WomanMotion.WebApi.Model.Dtos;
using WomanMotion.WebApi.Service;
using WomanMotion.WebApi.Service.IService;
using WomanMotion.WebApi.Infrastructure.Common;
using WomanMotion.WebApi.Model.Dtos.Team;
using Microsoft.AspNetCore.Authorization;
using WomanMotion.WebApi.Identity.JWT;
using NewLife.Redis.Core;
using NewLife.Caching;
using WomanMotion.WebApi.Service.Service;
using Lazy.Captcha.Core;
using WomanMotion.WebApi.Model.Dtos.Router;
using WomanMotion.WebApi.Infrastructure.Email;
using MimeKit;
using AutoMapper;
using AngleSharp.Dom;
using WomanMotion.WebApi.Model.Entitys;
using WomanMotion.WebApi.Wechat.IService;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.WxaBusinessGetUserEncryptKeyResponse.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinUserInfoBatchGetRequest.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.TCBGetStatisticsRequest.Types;
using System.Linq.Expressions;

namespace WomanMotion.WebApi.Api.Controllers
{
    /// <summary>
    /// 用户管理
    /// </summary>
    [Route("api/[controller]/[action]")]
    [XSSFilter]
    [ApiController]
    [DescriptionName("用户管理", true, 20)]
    public class UserController : BaseController
    {
        /// <summary>
        /// 角色服务对象
        /// </summary>
        protected readonly IRoleService _role;

        /// <summary>
        /// 用户服务对象
        /// </summary>
        protected readonly IUsersService _users;

        /// <summary>
        /// 配置文件读取
        /// </summary>
        private readonly IConfiguration _configuration;

        private readonly INewLifeRedis _redisService;
        private readonly ICaptcha _captcha;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ISendMail _sendMail;
        private readonly IMapper _mapper;
        private readonly IWechatCommon _wechatCommon;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="role"></param>
        /// <param name="users"></param>
        public UserController(ILogger<UserController> logger, IRoleService role, IUsersService users, IConfiguration configuration, INewLifeRedis redisService, ICaptcha captcha, IHttpContextAccessor httpContextAccessor, ISendMail sendMail, IMapper mapper, IWechatCommon wechatCommon) : base(logger)
        {
            _role = role;
            _users = users;
            _configuration = configuration;
            _redisService = redisService;
            _captcha = captcha;
            _httpContextAccessor = httpContextAccessor;
            _sendMail = sendMail;
            _mapper = mapper;
            _wechatCommon = wechatCommon;
        }

        /// <summary>
        /// 管理员创建用户
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns>实体信息</returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("管理员创建用户", true, "用户管理", "List", "UserList")]
        public async Task<IResultOutput> Created(CreatedUserDTO dto)
        {
            if (await _users.GetAnyAsync(m => m.Name == dto.Name))
            {
                return ResultOutput.NotOk("存在相同的用户名,添加失败");
            }
            if (await _users.GetAnyAsync(m => m.Email == dto.Email))
            {
                return ResultOutput.NotOk("存在相同的邮箱,添加失败");
            }
            if (await _users.GetAnyAsync(m => m.Phone == dto.Phone))
            {
                return ResultOutput.NotOk("存在相同的手机号,添加失败");
            }
            dto.Password = dto.Password.Sha256().Sha512();
            if (dto.Wxid == "")
            {
                dto.Wxid = null;
            }
            var res = await _users.CreatedAsync(dto);
            if (res != null)
            {
                //加入缓存
                _redisService.Set("user_ifdisable_" + res.Id, res.Ifdisable.ToString());
                //获取用户的角色信息
                var rolevm = await _role.GetByIdAsync(res.Roleid);
                //用户所属的角色加入缓存
                var redisuserrolename = "user_rolecode_" + res.Id;
                var redisuserrolevalue = rolevm.Code;
                //如果存在缓存先移除
                _redisService.Remove(redisuserrolename);
                //然后在添加保证是最新
                _redisService.Set(redisuserrolename, redisuserrolevalue);
                return ResultOutput.Ok(res, "操作成功");
            }
            else
            {
                return ResultOutput.NotOk("添加失败");
            }
        }

        /// <summary>
        /// 前端普通用户创建用户
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("前端普通用户创建用户")]
        [AllowAnonymous]
        public async Task<IResultOutput> CreatedOrdinary(CreatedUserDTO dto)
        {
            if (await _users.GetAnyAsync(m => m.Name == dto.Name))
            {
                return ResultOutput.NotOk("存在相同的用户名,添加失败");
            }
            if (await _users.GetAnyAsync(m => m.Email == dto.Email))
            {
                return ResultOutput.NotOk("存在相同的邮箱,添加失败");
            }
            if (await _users.GetAnyAsync(m => m.Phone == dto.Phone))
            {
                return ResultOutput.NotOk("存在相同的手机号,添加失败");
            }
            //当客户端传了微信code
            if (dto.Wxid != null && dto.Wxid != "")
            {
                var wxres = await _wechatCommon.GetOpenidAsync(dto.Wxid);
                if (wxres.Key == 1)
                {
                    dto.Wxid = wxres.Value;
                    if (await _users.GetAnyAsync(m => m.Wxid == dto.Wxid))
                    {
                        return ResultOutput.NotOk("此微信已经绑定过其他账号,注册失败");
                    }
                }
                else
                {
                    return ResultOutput.NotOk("微信code错误:" + wxres.Value);
                }
            }
            else
            {
                dto.Wxid = null;
            }
            dto.Password = dto.Password.Sha256().Sha512();
            //查询普通角色的id
            var role = await _role.GetAsync(m => m.Code == "ordinary");
            dto.Roleid = role.Id;
            var res = await _users.CreatedAsync(dto);
            if (res != null)
            {
                //加入缓存
                _redisService.Set("user_ifdisable_" + res.Id, res.Ifdisable.ToString());
                //获取用户的角色信息
                var rolevm = await _role.GetByIdAsync(res.Roleid);
                //用户所属的角色加入缓存
                var redisuserrolename = "user_rolecode_" + res.Id;
                var redisuserrolevalue = rolevm.Code;
                //如果存在缓存先移除
                _redisService.Remove(redisuserrolename);
                //然后在添加保证是最新
                _redisService.Set(redisuserrolename, redisuserrolevalue);
                return ResultOutput.Ok(res, "操作成功");
            }
            else
            {
                return ResultOutput.NotOk("添加失败");
            }
        }

        /// <summary>
        /// 启用用户
        /// </summary>
        /// <param name="ids">id主键数组</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate), (int)HttpStatusCode.OK)]
        [DescriptionName("启用用户")]
        public async Task<IResultOutput> Enable(PrimaryKeyDTO ids)
        {
            var res = await _users.UpdateDisableAsync(DisableEnum.Enable, ids.Ids);
            if (res > 0)
            {
                foreach (var item in ids.Ids)
                {
                    var redisname = "user_ifdisable_" + item;
                    //如果存在缓存先移除
                    _redisService.Remove(redisname);
                    //然后在添加保证是最新
                    _redisService.Set(redisname, "1");
                }
                return ResultOutput.Ok(new object(), "操作成功");
            }
            else
            {
                return ResultOutput.NotOk("操作失败");
            }
        }

        /// <summary>
        /// 禁用用户
        /// </summary>
        /// <param name="ids">id主键数组</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate), (int)HttpStatusCode.OK)]
        [DescriptionName("禁用用户")]
        public async Task<IResultOutput> Disable(PrimaryKeyDTO ids)
        {
            var users = await _users.GetListAsync(m => ids.Ids.Contains(m.Id));
            var usernames = users.Select(x => x.Name).Where(s => s == "admin").ToList();
            if (usernames.Count > 0)
            {
                return ResultOutput.NotOk("不允许禁用admin账号");
            }
            var res = await _users.UpdateDisableAsync(DisableEnum.Disable, ids.Ids);
            if (res > 0)
            {
                foreach (var item in ids.Ids)
                {
                    var redisname = "user_ifdisable_" + item;
                    //如果存在缓存先移除
                    _redisService.Remove(redisname);
                    //然后在添加保证是最新
                    _redisService.Set(redisname, "0");
                }
                return ResultOutput.Ok(new object(), "操作成功");
            }
            else
            {
                return ResultOutput.NotOk("操作失败");
            }
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns>实体信息</returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("更新用户")]
        public async Task<IResultOutput> Update(UpdateUserDTO dto)
        {
            var ent = await _users.GetEntityAsync(m => m.Id == dto.Id);
            if (ent == null || ent.Name != dto.Name)
            {
                return ResultOutput.NotOk("数据不存在或者不允许修改用户名");
            }
            dto.Wxid = ent.Wxid;
            var res = await _users.UpdateAsync(dto);
            if (res == null)
            {
                return ResultOutput.NotOk("操作失败");
            }
            var redisname = "user_ifdisable_" + res.Id;
            //如果存在缓存先移除
            _redisService.Remove(redisname);
            //然后在添加保证是最新
            _redisService.Set(redisname, res.Ifdisable.ToString());
            //获取用户的角色信息
            var rolevm = await _role.GetByIdAsync(res.Roleid);
            //用户所属的角色加入缓存
            var redisuserrolename = "user_rolecode_" + res.Id;
            var redisuserrolevalue = rolevm.Code;
            //如果存在缓存先移除
            _redisService.Remove(redisuserrolename);
            //然后在添加保证是最新
            _redisService.Set(redisuserrolename, redisuserrolevalue);
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 修改用户密码(管理员可修改任意用户)
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<int>), (int)HttpStatusCode.OK)]
        [DescriptionName("修改用户密码(管理员可修改任意用户)")]
        public async Task<IResultOutput> UpdatePwd(UpdateUserPwdDTO dto)
        {
            dto.Password = dto.Password.Sha256().Sha512();
            var res = await _users.UPdatePwdAsync(dto);
            if (!res)
            {
                return ResultOutput.NotOk("操作失败");
            }
            return ResultOutput.Ok(new object(), "操作成功");
        }

        /// <summary>
        /// 普通用户修改密码
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<int>), (int)HttpStatusCode.OK)]
        [DescriptionName("普通用户修改密码")]
        public async Task<IResultOutput> UpdateOrdinaryPwd(UpdateUserOrdinaryPwdDTO dto)
        {
            var userid = _httpContextAccessor.HttpContext.User.Claims.Where(m => m.Type == "UserId").First().Value;
            var isexist = await _users.GetAnyAsync(m => m.Id == long.Parse(userid) && m.Password == dto.OldPassword.Sha256().Sha512());
            if (!isexist)
            {
                return ResultOutput.NotOk("旧密码不正确");
            }
            var newdto = new UpdateUserPwdDTO() { Id = long.Parse(userid), Password = dto.NewPassword.Sha256().Sha512() };
            var res = await _users.UPdatePwdAsync(newdto);
            if (!res)
            {
                return ResultOutput.NotOk("操作失败");
            }
            return ResultOutput.Ok(new object(), "操作成功");
        }

        /// <summary>
        /// 普通用户修改头像
        /// </summary>
        /// <param name="photo"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("普通用户修改头像")]
        public async Task<IResultOutput> UpdatePhoto(string photo)
        {
            var userid = _httpContextAccessor.HttpContext.User.Claims.Where(m => m.Type == "UserId").First().Value;
            var vm = await _users.GetAsync(m => m.Id == long.Parse(userid));
            if (vm == null)
            {
                return ResultOutput.NotOk("用户不存在");
            }
            vm.Photo = photo;
            var ent = _mapper.Map<UserVM, UpdateUserDTO>(vm);
            var res = await _users.UpdateAsync(ent);
            if (res == null)
            {
                return ResultOutput.NotOk("操作失败");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 前端用户绑定微信
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<int>), (int)HttpStatusCode.OK)]
        [DescriptionName("前端用户绑定微信")]
        public async Task<IResultOutput> BindWeixin(string code)
        {
            var useridstr = _httpContextAccessor.HttpContext.User.Claims.Where(m => m.Type == "UserId").First().Value;
            long userid = long.Parse(useridstr);
            var vm = await _users.GetEntityAsync(m => m.Id == userid);
            if (vm == null)
            {
                return ResultOutput.NotOk("用户不存在");
            }
            if (vm.Wxid != null && vm.Wxid != "")
            {
                return ResultOutput.NotOk("该用户已经绑定了微信，不用重复绑定");
            }
            var wxres = await _wechatCommon.GetOpenidAsync(code);

            if (wxres.Key != 1)
            {
                return ResultOutput.NotOk("微信code错误:" + wxres.Value);
            }
            else
            {
                var wxid = wxres.Value;
                if (await _users.GetAnyAsync(m => m.Id != userid && m.Wxid == wxid))
                {
                    return ResultOutput.NotOk("此微信绑定了其他账号,绑定失败");
                }
                vm.Wxid = wxid;
                var res = await _users.UpdateEntityAsync(vm);

                if (res == null)
                {
                    return ResultOutput.NotOk("操作失败");
                }
                return ResultOutput.Ok(res, "操作成功");
            }
        }

        /// <summary>
        /// 前端用户解除绑定微信
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<int>), (int)HttpStatusCode.OK)]
        [DescriptionName("前端用户解除绑定微信")]
        public async Task<IResultOutput> RelieveWeixin()
        {
            var useridstr = _httpContextAccessor.HttpContext.User.Claims.Where(m => m.Type == "UserId").First().Value;
            long userid = long.Parse(useridstr);
            var vm = await _users.GetEntityAsync(m => m.Id == userid);
            if (vm == null)
            {
                return ResultOutput.NotOk("用户不存在");
            }
            if (vm.Wxid == null || vm.Wxid == "")
            {
                return ResultOutput.NotOk("该用户已经没有绑定微信，不需要解绑");
            }
            vm.Wxid = null;
            var res = await _users.UpdateEntityAsync(vm);

            if (res == null)
            {
                return ResultOutput.NotOk("操作失败");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 前端用户修改用户资料
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<int>), (int)HttpStatusCode.OK)]
        [DescriptionName("前端用户修改用户资料")]
        public async Task<IResultOutput> LeadingUpdate(LeadingUpdateUserDto dto)
        {
            var useridstr = _httpContextAccessor.HttpContext.User.Claims.Where(m => m.Type == "UserId").First().Value;
            long userid = long.Parse(useridstr);
            var vm = await _users.GetEntityAsync(m => m.Id == userid);
            if (vm == null)
            {
                return ResultOutput.NotOk("用户不存在");
            }
            if (await _users.GetAnyAsync(m => m.Id == userid && m.Email == dto.Email))
            {
                return ResultOutput.NotOk("存在相同的邮箱,修改失败");
            }
            if (await _users.GetAnyAsync(m => m.Id == userid && m.Phone == dto.Phone))
            {
                return ResultOutput.NotOk("存在相同的手机号,修改失败");
            }
            vm.Email = dto.Email;
            vm.Phone = dto.Phone;
            var res = await _users.UpdateEntityAsync(vm);
            if (res == null)
            {
                return ResultOutput.NotOk("操作失败");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 根据ID查询用户信息
        /// </summary>
        /// <param name="id">id主键</param>
        /// <returns>实体信息</returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("根据ID查询用户信息")]
        public async Task<IResultOutput> GetById(long id)
        {
            var res = await _users.GetByIdAsync(id);
            if (res == null)
            {
                return ResultOutput.NotOk("没有数据");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 查询自己的用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("查询自己的用户信息")]
        public async Task<IResultOutput> GetUserInfo()
        {
            var userid = _httpContextAccessor.HttpContext.User.Claims.Where(m => m.Type == "UserId").First().Value;
            var res = await _users.GetByIdAsync(long.Parse(userid));
            if (res == null)
            {
                return ResultOutput.NotOk("没有数据");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 根据ID获取多表连接用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserPageVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("根据ID获取多表连接用户信息")]
        public async Task<IResultOutput> GetCommonById(long id)
        {
            var res = await _users.GetCommonFirstAsync(id);
            if (res == null)
            {
                return ResultOutput.NotOk("没有数据");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 分页获取用户数据
        /// </summary>
        /// <param name="pars">查询参数</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<PageViewBase<List<UserPageVM>>>), (int)HttpStatusCode.OK)]
        [DescriptionName("分页获取用户数据")]
        public async Task<IResultOutput> GetPageList(QueryParameterBase pars)
        {
            var res = await _users.GetCommonPageListAsync(pars);
            if (res.Data == null || res.Data.Count == 0)
            {
                return ResultOutput.NotOk("没有数据");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserTokenVM>), (int)HttpStatusCode.OK)]
        [AllowAnonymous]
        [DescriptionName("用户登录")]
        public async Task<IResultOutput> UserLogin(UserLoginDTO dto)
        {
            var iscap = _captcha.Validate(dto.captchaid, dto.captchacode);
            if (!iscap)
            {
                return ResultOutput.NotOk("验证码输入错误");
            }
            dto.Password = dto.Password.Sha256().Sha512();
            var res = await _users.GetAnyAsync(m => m.Name == dto.Name && m.Password == dto.Password && m.Ifdisable == 1);
            if (!res)
            {
                return ResultOutput.NotOk("登录失败");
            }
            else
            {
                //获取用户信息
                var uservm = await _users.GetCommonFirstAsync(m => m.Name == dto.Name);
                var userTokenVM = SetToken(uservm);
                return ResultOutput.Ok(userTokenVM, "登录成功");
            }
        }

        /// <summary>
        /// 用户登录微信授权
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<UserTokenVM>), (int)HttpStatusCode.OK)]
        [AllowAnonymous]
        [DescriptionName("用户登录微信授权")]
        public async Task<IResultOutput> UserWXLogin(string code)
        {
            //微信微信的openid
            var wxres = await _wechatCommon.GetOpenidAsync(code);
            if (wxres.Key == 1)
            {
                var uservm = await _users.GetAsync(m => m.Wxid == wxres.Value && m.Ifdisable == 1);
                if (uservm == null)
                {
                    return ResultOutput.NotOk("登录失败，此微信没有绑定账号或者账号已禁用");
                }
                else
                {
                    //获取用户信息
                    var userpgvm = await _users.GetCommonFirstAsync(m => m.Id == uservm.Id);
                    var userTokenVM = SetToken(userpgvm);
                    return ResultOutput.Ok(userTokenVM, "登录成功");
                }
            }
            else
            {
                return ResultOutput.NotOk("微信code错误:" + wxres.Value);
            }
        }

        /// <summary>
        /// 查询当前openid是否有没有注册账号
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<bool>), (int)HttpStatusCode.OK)]
        [AllowAnonymous]
        [DescriptionName("查询当前openid是否有没有注册账号")]
        public async Task<IResultOutput> UserIOpenid(string code)
        {
            //微信微信的openid
            var wxres = await _wechatCommon.GetOpenidAsync(code);
            if (wxres.Key == 1)
            {
                _logger.LogInformation("openid:" + wxres.Value);
                var uservm = await _users.GetAsync(m => m.Wxid == wxres.Value);
                if (uservm != null)
                {
                    return ResultOutput.Ok(true, "已经存在此openid");
                }
                else
                {
                    return ResultOutput.NotOk("不存在此openid:" + wxres.Value);
                }
            }
            else
            {
                return ResultOutput.NotOk("微信code错误:" + wxres.Value);
            }
        }

        /// <summary>
        /// 登录获取Token
        /// </summary>
        /// <param name="uservm"></param>
        /// <returns></returns>
        private UserTokenVM SetToken(UserPageVM uservm)
        {
            //获取token配置文件
            var tokenMoble = _configuration.GetSection("Jwt").Get<TokenModelJwt>();
            tokenMoble.UserId = uservm.Id;
            tokenMoble.UserName = uservm.Name;
            tokenMoble.RoleCode = uservm.RoleCode;
            var userTokenVM = new UserTokenVM();
            userTokenVM.refreshexpires = JwtHelper.CreateJwtRefresh(tokenMoble);
            userTokenVM.accessexpires = JwtHelper.CreateJwtAccess(tokenMoble);
            var refexpdatetime = DateTime.Now.AddDays(double.Parse(_configuration.GetSection("Jwt:RefreshExpires").Value) - 1);//为了保险 减去1
            var accexpdatetime = DateTime.Now.AddMinutes(double.Parse(_configuration.GetSection("Jwt:AccessExpires").Value) - 1);//为了保险 减去1 	acctime	{2023/3/14 14:42:40}
            var refexptimestamp = (long.Parse(_configuration.GetSection("Jwt:RefreshExpires").Value) - 1) * 86400000;
            var accexptimestamp = (long.Parse(_configuration.GetSection("Jwt:AccessExpires").Value) - 1) * 60000;
            userTokenVM.refexpdatetime = refexpdatetime;
            userTokenVM.accexpdatetime = accexpdatetime;
            userTokenVM.refexptimestamp = refexptimestamp;
            userTokenVM.accexptimestamp = accexptimestamp;
            userTokenVM.data = uservm;
            return userTokenVM;
        }

        /// <summary>
        /// 刷新短token
        /// </summary>
        /// <param name="dto">长token</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<RefreshTokenVM>), (int)HttpStatusCode.OK)]
        [AllowAnonymous]
        [DescriptionName("刷新短token")]
        public IResultOutput RefreshToken(RefreshTokenDTO dto)
        {
            //获取token配置文件
            var tokenConfigMoble = _configuration.GetSection("Jwt").Get<TokenModelJwt>();
            var tokenMoble = JwtHelper.SerializeRefreshToken(tokenConfigMoble, dto.reftoken);
            if (tokenMoble == null)
            {
                return ResultOutput.NotOk("token验证失败");
            }
            tokenConfigMoble.UserId = tokenMoble.UserId;
            tokenConfigMoble.UserName = tokenMoble.UserName;
            tokenConfigMoble.RoleCode = tokenMoble.RoleCode;
            var res = new RefreshTokenVM();
            res.refreshexpires = dto.reftoken;
            res.accessexpires = JwtHelper.CreateJwtAccess(tokenConfigMoble);
            res.accexpdatetime = DateTime.Now.AddMinutes(double.Parse(_configuration.GetSection("Jwt:AccessExpires").Value) - 1);//为了保险 减去1
            res.accexptimestamp = (long.Parse(_configuration.GetSection("Jwt:AccessExpires").Value) - 1) * 60000;
            res.Name = tokenConfigMoble.UserName;
            res.RoleCode = tokenConfigMoble.RoleCode;
            return ResultOutput.Ok(res, "刷新token成功");
        }

        /// <summary>
        /// 发送找回密码的邮件验证码
        /// </summary>
        /// <param name="email">email地址</param>
        /// <param name="key">key</param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<int>), (int)HttpStatusCode.OK)]
        [AllowAnonymous]
        [DescriptionName("发送找回密码的邮件验证码")]
        public async Task<IResultOutput> EmailVerificationCode(string email, string key)
        {
            var user = await _users.GetAsync(m => m.Email == email && m.Ifdisable == 1);
            if (user == null)
            {
                return ResultOutput.NotOk("没有查询到邮箱绑定的账号或账号已禁用");
            }
            //获取随机字符串
            string code = Tools.Radomstrs(6);
            var message = new MimeMessage
            {
                Subject = "你的密码找回验证码",
                Body = new BodyBuilder
                {
                    HtmlBody = user.Name + $"  你的密码找回验证码为:  " + code + $"        时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"
                }.ToMessageBody()
            };
            try
            {
                var emailmodel = new EmailVerificationCodeModel() { email = email, code = code, key = key };
                await _sendMail.SendEmailAsync(message, user.Name, email);
                //添加缓存
                _redisService.Set(email + "_" + key + "_" + code, emailmodel, 1800);
                return ResultOutput.Ok(new object(), "获取路由成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return ResultOutput.NotOk("邮件验证码发送失败，请联系管理员");
            }
        }

        /// <summary>
        /// 邮箱验证码修改密码
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<int>), (int)HttpStatusCode.OK)]
        [AllowAnonymous]
        [DescriptionName("邮箱验证码修改密码")]
        public async Task<IResultOutput> EmailRetrievePasswd(EmailRetrievePasswdDTO dto)
        {
            var cachekey = dto.Email + "_" + dto.Verificationkey + "_" + dto.Verificationcode;
            //查询缓存
            var isexist = _redisService.ContainsKey(cachekey);
            if (!isexist)
            {
                return ResultOutput.NotOk("密码修改失败,验证码不匹配");
            }
            //查询用户
            var user = await _users.GetAsync(m => m.Email == dto.Email && m.Ifdisable == 1);
            if (user == null)
            {
                return ResultOutput.NotOk("没有查询到邮箱绑定的账号或账号已禁用");
            }
            var newdto = new UpdateUserPwdDTO() { Id = user.Id, Password = dto.Password.Sha256().Sha512() };
            var res = await _users.UPdatePwdAsync(newdto);
            if (!res)
            {
                return ResultOutput.NotOk("修改失败");
            }
            _redisService.Remove(cachekey);
            return ResultOutput.Ok(new object(), "操作成功");
        }

        /// <summary>
        /// 获取前端路由
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<RouterVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("获取前端路由")]
        public async Task<IResultOutput> GetRoute()
        {
            var res = await _users.GetRoute();
            if (res != null)
            {
                return ResultOutput.Ok(res, "获取路由成功");
            }
            else
            {
                return ResultOutput.NotOk("获取路由失败");
            }
        }
    }
}